﻿/* isiri2901.js - Standard Persian keyboard driver for JavaScript
*
* Copyright (C) 2000  Roozbeh Pournader
* Copyright (C) 2003, 2005  Behdad Esfahbod
* Copyright (C) 2005  Pooya Karimian
* Copyright (C) 2005  Behnam Esfahbod
* 
* ChangeLog:
* Mar 05, 2005  Pooya Karimian, FireFox/Mozilla support added.
* Mar 20, 2005  Behdad Esfahbod, random fixes in Firefox support.
* Apr 14, 2005  Behnam Esfahbod, U+0654, U+0670, U+00F7 added.
* Apr 21, 2005  Behdad Esfahbod, Minimal Opera 8.0 support added.
*               Alt+Ctrl+anything now is known to switch language.
* September 25, 2006 Mani Malekmohammadi, added replace for ی and ک and گ 
* May 14, 2006 Mani Malekmohammadi, added replace for پ
*
*http://www.pooyak.com/p/persianjavascript/
*
* Licensed under GNU GPL.
*/

var isiri2901_lang = 1; // 1: Persian, 0: English
var isiri2901_nativelang = 0;  // 1: Persian, 0: English

// Persian keyboard map based on ISIRI-2901
// MANI: http://www.isiri.org/std/2901.htm
// MANI: http://www.m17n.org/emacs-bidi/isiri2901.html  --> Mapping table of the persian-isiri2901 input method

var isirikey = [
  0x0020, 0x0021, 0x061B, 0x066B, 0x00A4, 0x066A, 0x060C, 0x06AF,
  0x0029, 0x0028, 0x002A, 0x002B, 0x0648, 0x002D, 0x002E, 0x002F,
  0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, 0x06F7,
  0x06F8, 0x06F9, 0x003A, 0x06A9, 0x003E, 0x003D, 0x003C, 0x061F,
  0x066C, 0x0624, 0x200C, 0x0698, 0x064A, 0x064D, 0x0625, 0x0623,
  0x0622, 0x0651, 0x0629, 0x00BB, 0x00AB, 0x0621, 0x0654, 0x005D,
  0x005B, 0x0652, 0x064B, 0x0626, 0x064F, 0x064E, 0x0670, 0x064C,
  0x00F7, 0x0650, 0x0643, 0x062C, 0x005C, 0x0686, 0x00D7, 0x0640,
  0x200D, 0x0634, 0x0630, 0x0632, 0x06CC, 0x062B, 0x0628, 0x0644,
  0x0627, 0x0647, 0x062A, 0x0646, 0x0645, 0x067E, 0x062F, 0x062E,
  0x062D, 0x0636, 0x0642, 0x0633, 0x0641, 0x0639, 0x0631, 0x0635,
  0x0637, 0x063A, 0x0638, 0x007D, 0x007C, 0x007B, 0x007E
];


function PersianKeyPress(e, lang) {
    var key;
    var obj;

    if (window.navigator.appName == 'Microsoft Internet Explorer') {
        e = window.event;
        obj = e.srcElement;
        key = e.keyCode;
    } else {
        obj = e.target;
        key = e.charCode;
    }


    if (e.bubbles == false) {
        return true;
    }


    // avoid replacing english charachters
    if (key < 1000)
        return true;

    //   This cannot be used anymore, in FF 1.5.0.2, as a new event will call keypress again.
    //   Change to English, if user is using an OS non-English keyboard
    if (lang == 'fa')
        setPersian();

    if (lang == 'en' && key != 1610 && key != 1603) {
        return true;
    }

    // replace 1610 with 1740
    if (key == 1610) // replace ي with ی
        key = 100;

    // replace 1603 with 1705
    if (key == 1603) // replace ك with ک
        key = 59;


    // Avoid processing if control or higher than ASCII
    // Or ctrl or alt is pressed.
    if (lang == 'fa' && (key < 32 || key >= 126 || e.ctrlKey || e.altKey || e.metaKey)) {
        return true;
    }

    // rewrite key
    var newkey;

    // MANI : adding پ for different keyboard layouts
    if (key == 92 || key == 96)
        key = 109;

    if (key == 32 && e.shiftKey) // Shift-space -> ZWNJ
        newkey = 8204;
    else
        newkey = isirikey[key - 32];

    if (newkey == key) {
        return true;
    }

    try {
        // Gecko 
        var new_event = document.createEvent("KeyEvents");
        new_event.initKeyEvent("keypress", false, true, document.defaultView, false, false, false, false, 0, newkey);
        obj.dispatchEvent(new_event);
        e.preventDefault();
    } catch (err) {
        try {
            // Windows
            e.keyCode = newkey;
        } catch (err) {
            try {
                // Gecko after banning fake key emission (FF 1.0.6 to FF 1.5.0.1)
                // Try inserting at cursor position
                pnhMozStringInsert(obj, String.fromCharCode(newkey));
                e.preventDefault();
            } catch (err) {
                // Everything else, simply add to the end of buffer
                obj.value += String.fromCharCode(newkey);
                e.preventDefault();
            } 
        } 
    }

    return true;
}


function setPersian(obj, quiet) {
    isiri2901_lang = 1;
    if (obj) {
        obj.style.textAlign = "right";
        obj.style.direction = "rtl";
        obj.focus();
    }
    if (!quiet)
        window.status = "Persian Keyboard";
}


function setEnglish(obj, quiet) {
    isiri2901_lang = 0;
    if (obj) {
        obj.style.textAlign = "left";
        obj.style.direction = "ltr";
        obj.focus();
    }
    if (!quiet)
        window.status = "English Keyboard";
}


function toggleDir(obj, quiet) {
    if (obj && obj.style.direction == 'ltr' || !obj && isiri2901_lang == 1)
        setPersian(obj, quiet);
    else
        setEnglish(obj, quiet);
}



